var express = require('express')
var proxy = require('express-http-proxy');
var expressWs = require('express-ws') // 引入 WebSocket 包
var sqlite3 = require('sqlite3').verbose()
var cookieParser=require('cookie-parser')
var bodyParser = require('body-parser')
var session = require("express-session")
var fs = require('fs')
var https = require('https')
var http = require('http')
var nobadyroom = require('./nobodyroom')
var dbinit = require('./dbinit')
var indexConfig = require('./indexConfig')
var userConfig = require('./userConfig')
var path = require('path')
/**
 * 将指定src目录下的所有文件剪切到指定目标dest目录下
 * @param src 源目录
 * @param dest 目标目录
 */
 function copyDirectory(src, dest) {
    var files = fs.readdirSync(src)
    files.forEach((item, index) => {
        var itemPath = path.join(src, item)
        var itemStat = fs.statSync(itemPath)// 获取文件信息
        var savedPath = path.join(dest, itemPath.replace(src, ''))
        var savedDir = savedPath.substring(0, savedPath.lastIndexOf('/'))
        if (itemStat.isFile()) {
            // 如果目录不存在则进行创建
            if (!fs.existsSync(savedDir)) {
                fs.mkdirSync(savedDir, {recursive: true})
            }
            // 写入到新目录下
            var data = fs.readFileSync(itemPath)
            fs.writeFileSync(savedPath, data)
        } else if (itemStat.isDirectory()) {
            copyDirectory(itemPath, path.join(savedDir, item))
        }
    })
}

//配置文件夹
const configdir = './config'
if (fs.existsSync(configdir)) {
    console.log('configdir exists!')
} else {
    fs.mkdirSync(configdir)
}

//反向代理配置
const proxyConfig = './config/proxy.json'
if (fs.existsSync(proxyConfig)) {
    console.log('proxyConfig exists!')
} else {
    fs.writeFileSync(proxyConfig, '[]')
}

//页面
const htmldir = './config/html'
if (fs.existsSync(htmldir)) {
    console.log('htmldir exists!')
} else {
    copyDirectory('./html',configdir)
}

//https证书
const httpskeys = './config/keys'
if (fs.existsSync(httpskeys)) {
    console.log('httpskeysdir exists!')
} else {
    copyDirectory('./keys',configdir)
}

//静态公开资源
const resourcesdir = './config/resources'
if (fs.existsSync(resourcesdir)) {
    console.log('httpskeysdir exists!')
} else {
    fs.mkdirSync(resourcesdir)
}

const dbname = './config/dksqlite.db'
// 创建并连接一个数据库
const db = new sqlite3.Database(dbname)
dbinit.dbinit(db)

var options = {
    key:fs.readFileSync(httpskeys+'/server.key'),
    cert:fs.readFileSync(httpskeys+'/server.crt')
}

var app = express()
app.use(bodyParser.urlencoded({extended: false}))
app.use(bodyParser.json())
app.use(cookieParser())
// session 中间件
app.use(session({
    secret: 'keyboard cat',   // 加密字符串会通过这个字符串进行加密,自己可以设置
    cookie: {maxAge:31104000000},   // 设置过期时间,也可以在里面设置其他的想要的cookie属性
    resave: true,   // 即时session 没有被修改, 也保存session值, 默认为true
    saveUninitialized:true, //  无论有没有session cookie 每次请求都设置个session cookie 默认标示为 connect.sid
    rolling: true   // 属性cookie的时间
}))
expressWs(app)
//跨域设置
app.all("*", function (req, res, next) {
    res.setHeader("Access-Control-Allow-Credentials", true)
    try {
        res.setHeader("Access-Control-Allow-Origin", req.get("Origin")) // 添加这一行代码，代理配置不成功
    } catch (error) {
        res.setHeader("Access-Control-Allow-Origin", '*')
    }
    res.setHeader("Access-Control-Allow-Methods", 'POST, GET, OPTIONS, DELETE, PUT')
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, If-Modified-Since")
    //初始化
    if (!req.session.user) {
        console.log('New req')
        try {
            let getClientIp = function (req) {
                return req.headers['x-forwarded-for'] ||
                    req.connection.remoteAddress ||
                    req.socket.remoteAddress ||
                    req.connection.socket.remoteAddress || ''
            }
            let ip = getClientIp(req).match(/\d+.\d+.\d+.\d+/)
            console.log(ip)
        } catch (error) {
            console.log('???')
        }

        db.all(`SELECT * FROM user where id = 0`,function(err,res){
            if (err) {
                req.session.user = {
                    id: 0,
                    name: '游客',
                    email: 'tourist@tourist',
                    photo: null
                }
            }else{
                req.session.user = res[0]
            }
            next()
        })
    }else{
        next()
    }
})

app.use(express.static(htmldir))
app.use('/resources', express.static(resourcesdir))

fs.readFile(proxyConfig, 'utf-8', function(err, data) {
    if (!err) {
        console.log(data)
        try {
            const proxyList = JSON.parse(data)
            for (let index = 0; index < proxyList.length; index++) {
                const element = proxyList[index];
                console.log(element)
                app.use(element.path,proxy(element.proxy,{}))
            }
        } catch (error) {
            console.log(error)
        }
    }else{
        console.log(err)
    }
})

nobadyroom.nobadyroom(app)
indexConfig.indexConfig(app,db)
userConfig.userConfig(app,db)

var httpsServer = https.createServer(options,app)
var httpServer = http.createServer(app)

//https监听38443端口
httpsServer.listen(443)
//http监听38081端口
httpServer.listen(80)